package com.leo.biz.service.zookeeper;

import com.leo.biz.service.pub.TypeUtils;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;

import java.util.List;

/**
 * Created by leo on 2016/11/5.
 */
public class ZkClient {

    static Logger logger = org.slf4j.LoggerFactory.getLogger(ZkTest.class);

    private static final String zookeeperUrl="192.168.32.128:2181";


    /*向ZooKeeper中心注册本服务,并将配置写入到指定路径下
    * 路径 String path
    * 名称 String name
    * 数据 byte[] data
    *
    * */
    public static void register(String path,String name,byte[] datas) throws Exception {

        ZooKeeper zk = new ZooKeeper(zookeeperUrl, 30000, new Watcher() {
            // 监控所有被触发的事件
            public void process(WatchedEvent event) {
                logger.info("注册保活|监听到事件:" + event.getState() + ":" + event.getType() + ":" + event.getWrapper() + ":" + event.getPath());
            }
        });

        if(zk.exists(path, true) == null)
        {
            String tempPath=path;
            if(tempPath.startsWith("/"))
            {
                tempPath=tempPath.substring(1);
            }
            String[] pathPart=tempPath.split("/");
            String curPath="";
            for(int i=0;i<pathPart.length;i++)
            {
                curPath=curPath+"/"+pathPart[i];
                if(zk.exists(curPath, true) == null)
                {
                    zk.create(curPath, curPath.getBytes("UTF-8"), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
                }
            }
        }

        if(zk.exists(path+"/"+name, true)==null)
        {
            //创建临时节点来保证此节点在连接可用时，才被激活。从而保证服务可用性的监测
            zk.create(path + "/" + name, name.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
            Stat stat=zk.setData(path+"/"+name,datas,-1);
        }

        byte[] testData=zk.getData(path+"/"+name,false,null);
        logger.info("service register success| "+path + "/" + name+"| data set success:value="+new String(datas));
    }


    /**从配置中心读取当前的可用服务节点列表
     * path：节点父路径
     * @return List<String>服务节点路径
     * */
    public static List<String> getActiveServiceNode(String path)throws Exception
    {
        ZooKeeper zk = new ZooKeeper(zookeeperUrl, 30000, new Watcher() {
            // 监控所有被触发的事件
            public void process(WatchedEvent event) {
                logger.info("服务发现|监听到事件:" + event.getState() + ":" + event.getType() + ":" + event.getWrapper() + ":" + event.getPath());
            }
        });
        List<String> retList=zk.getChildren(path, false);
        if(retList!=null)
        {
            logger.info(retList.size()+" active service node:"+ TypeUtils.list2Str(retList, ","));
        }
        zk.close();
        return retList;
    }


    /**从配置中心读取某服务节点的配置
     * path：节点父路径
     * name:节点名称
     * @return byte[]
     * */
    public static byte[] getServiceNodeDatas(String path,String name)throws Exception
    {
        ZooKeeper zk = new ZooKeeper(zookeeperUrl, 30000, new Watcher() {
            // 监控所有被触发的事件
            public void process(WatchedEvent event) {
                logger.info("配置读取|监听到事件:" + event.getState() + ":" + event.getType() + ":" + event.getWrapper() + ":" + event.getPath());

            }
        });
        byte[] ret=zk.getData(path + "/" + name, true, null);
        if(ret!=null)
        {
            logger.info("get service datas success| "+path + "/" + name+"| data value="+new String(ret));
        }else
        {
            logger.error("get service datas failed");
        }
        return ret;
    }

    /**对配置中心某服务节点的配置进行设置
     * path：节点父路径
     * name:节点名称
     * @return byte[]
     * */
    public static void setServiceNodeDatas(String path,String name,byte[] datas)throws Exception
    {
        ZooKeeper zk = new ZooKeeper(zookeeperUrl, 30000, new Watcher() {
            // 监控所有被触发的事件
            public void process(WatchedEvent event) {
                logger.info("配置设置|监听到事件:" + event.getState() + ":" + event.getType() + ":" + event.getWrapper() + ":" + event.getPath());
            }
        });
        Stat ret=zk.setData(path + "/" + name, datas, -1);
        zk.close();

    }
}
































